// 起因: 没有被import的package不执行init, 导致spring.Register()未全部执行
package main

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
)

var (
	pkgs  = make(map[string]string, 100) // import
	dpkgs = make(map[string]int, 100)    // 避免变量的pkg重复
	mpkgs = make(map[string]bool, 100)   // 避免重复处理*.go
	vars  = make([]string, 0, 100)
)

func main() {
	//rootPath := "/home/chen/git/zstackgo/pkg"
	rootPath := "/home/chen/git/zstackgo/pkg/core/captcha"
	if err := GetAllFile(rootPath); err != nil {
		panic(err)
	}

	for k := range pkgs {
		ls := strings.Fields(k)
		if len(ls) > 1 {
			fmt.Println(ls[0] + ` "` + ls[1] + `"`)
		} else {
			fmt.Println(`"` + k + `"`)
		}
	}

	for _, v := range vars {
		fmt.Println(v)
	}
}

func GetAllFile(rp string) error {
	rd, err := os.ReadDir(rp)
	for _, fi := range rd {
		if fi.IsDir() {
			GetAllFile(filepath.Join(rp, fi.Name()))
		} else {
			var isInterface bool
			tp := filepath.Join(rp, fi.Name())
			pkg := strings.TrimPrefix(filepath.Dir(tp), "/home/chen/git/")
			ls := GetOneVar(tp)
			if len(ls) == 0 {
				ls = GetOneInterface(tp)
				if len(ls) == 0 {
					continue
				}
				isInterface = true
			}

			if mpkgs[pkg] {
				continue
			}
			mpkgs[pkg] = true

			// if filepath.Base(pkg) == "apimediator" {
			// 	fmt.Println(pkg)
			// } else {
			// 	continue
			// }

			if n := dpkgs[filepath.Base(pkg)]; n > 0 {
				first := 1
				for {
					npkg := filepath.Base(pkg) + fmt.Sprintf("_%d", first)
					if i := dpkgs[npkg]; i == 0 {
						dpkgs[npkg] = 1
						pkgs[npkg+" "+pkg] = ""

						for _, v := range ls {
							//fmt.Println(pkg + "@" + v)

							if !isInterface {
								vars = append(vars, "_="+npkg+"."+v+"{}")
							} else {
								vars = append(vars, "_=new("+npkg+"."+v+")")
							}

						}
						break
					}
					first++
				}
			} else {
				pkgs[pkg] = ""
				dpkgs[filepath.Base(pkg)] = 1

				for _, v := range ls {
					//fmt.Println(pkg + "@" + v)

					if !isInterface {
						vars = append(vars, "_="+filepath.Base(pkg)+"."+v+"{}")
					} else {
						vars = append(vars, "_=new("+filepath.Base(pkg)+"."+v+")")
					}
				}
			}

		}
	}
	return err
}

var (
	re  = regexp.MustCompile(`(?m)o := new\((\w+)\)`)
	rei = regexp.MustCompile(`(?m)spring\.RegisterInterface\("(.+)"`)
)

func GetOneVar(fp string) []string {
	data, err := os.ReadFile(fp)
	if err != nil {
		panic(err)
	}

	for _, matchs := range re.FindAllStringSubmatch(string(data), -1) {
		return []string{matchs[1]}
	}

	return nil
}

func GetOneInterface(fp string) []string {
	data, err := os.ReadFile(fp)
	if err != nil {
		panic(err)
	}

	for _, matchs := range rei.FindAllStringSubmatch(string(data), -1) {
		return []string{getInterfaceName(matchs[1])}
	}

	return nil
}

func getInterfaceName(name string) string {
	i := strings.LastIndex(name, ".")
	if i == -1 {
		return name
	} else {
		return name[i+1:]
	}
}
